home *** CD-ROM | disk | FTP | other *** search
- Subject: v14i050: Network News Transfer Protocol, version 1.5, Part04/09
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Phil Lapsley <phil@ucbvax.berkeley.edu>
- Posting-number: Volume 14, Issue 50
- Archive-name: nntp1.5/part04
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 4 (of 9)."
- # Wrapped by rsalz@fig.bbn.com on Tue Apr 19 18:16:41 1988
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f './common/conf.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./common/conf.h'\"
- else
- echo shar: Extracting \"'./common/conf.h'\" \(5753 characters\)
- sed "s/^X//" >'./common/conf.h' <<'END_OF_FILE'
- X/*
- X * Configuration information for use by NNTP server and support
- X * programs. Change these as appropriate for your system.
- X */
- X
- X/*
- X * Compile time options.
- X */
- X
- X#undef ALONE /* True if we're running without inetd */
- X#undef FASTFORK /* True if we don't want to read active file on start */
- X#undef BSD_42 /* 4.2 compatability code -- if this is defined, */
- X /* DBM probably wants to be defined as well. */
- X
- X#define NDBM /* Use new-style (4.3) ndbm(3x) libraries */
- X
- X#undef DBM /* True if we want to use the old dbm(3x) libraries */
- X /* IF YOU DEFINE THIS, change CFLAGS in makefile to */
- X /* be -ldbm */
- X
- X#undef USGHIST /* Use USG style history file (no DBM) */
- X /* IF YOU DO NOT DEFINE NDBM or DBM, this is DEFAULT! */
- X
- X#undef USG /* System V support */
- X#undef EXCELAN /* Excelan EXOS 205 support */
- X
- X#undef U_LONG /* Define this if your <sys/types.h> is missing */
- X /* typedefs for u_long */
- X
- X/*
- X * If you DON'T have vfork, make this "#define vfork fork"
- X * vfork will speed up article transfer nntpds by about 2.5 times.
- X */
- X
- X#undef vfork
- X
- X/*
- X * If you have the syslog library routine, define SYSLOG to
- X * be thef syslog facility name under which stats should be
- X * logged. Newer 4.3 systems might choose LOG_NEWS;
- X * LOG_LOCAL7 is an acceptable substitute.
- X *
- X * If you don't have support for syslog, but want a facsimile,
- X * define FAKESYSLOG to be the name of a file to which to log stuff,
- X * then define SYSLOG and LOG, too. e.g.,
- X *
- X * #define FAKESYSLOG "/usr/lib/news/nntplog"
- X *
- X * If you don't want any syslog-type activity, #undef SYSLOG.
- X * Obviously, this means that you can't define LOG, either.
- X */
- X
- X#undef FAKESYSLOG
- X
- X#define SYSLOG LOG_NEWS
- X
- X#ifdef SYSLOG /* Define LOG if you want copious logging info */
- X# define LOG /* undef it if you don't */
- X#endif /* but you can only have LOG if you have SYSLOG */
- X
- X#ifdef BSD_42 /* This is a logical, warranted assumption */
- X# ifndef DBM /* which will probably get me in trouble. */
- X# define DBM /* Kill it if you have 4.2 *and* ndbm. */
- X# endif not DBM
- X#endif BSD_42
- X
- X#ifdef USG /* Another similar assumption */
- X# ifndef USGHIST
- X# define USGHIST
- X# endif not USGHIST
- X#endif USG
- X
- X#undef IHAVE_DEBUG /* Copious debugging output from ihave */
- X
- X#define XHDR /* Optional XHDR command. Defining this will */
- X /* speed up '=' command in rn, but will load */
- X /* the server more. If your server is heavily */
- X /* loaded already, defining this may be a bad idea */
- X
- X#define SUBNET /* If you have 4.3 subnetting */
- X#undef DAMAGED_NETMASK /* If your subnet mask is not a multiple of */
- X /* four bits (e.g., UCSD) */
- X
- X#undef NETMASK /* If you don't have subnet ioctls, define */
- X /* this to be a hex constant of your subnet */
- X /* mask, e.g., #define NETMASK 0xffffff00 */
- X /* Of course, you must define SUBNET above, too. */
- X#undef DECNET /* If you want decnet support */
- X
- X#define GHNAME /* Define if you have gethostname() */
- X#undef UUNAME /* Define to use /etc/uucpname */
- X /* If neither of these are defined, */
- X /* inews will use the contents of */
- X /* /usr/include/whoami.h */
- X
- X/*
- X * System V compatability
- X */
- X
- X#ifdef USG
- X# define FCNTL /* If O_etc is defined in <fcntl.h> */
- X# define NDIR /* If you need ndir library support */
- X# define index strchr
- X# define rindex strrchr
- X# ifdef U_LONG
- X typedef unsigned long u_long;
- X typedef unsigned short u_short;
- X# endif U_LONG
- X# define IPPORT_NNTP 119
- X#endif USG
- X
- X/*
- X * How long you want nntp servers to hang out without receiving
- X * commands before they close the connection with an error message.
- X *
- X * You CANNOT have TIMEOUT while running in standalone (ALONE) mode,
- X * as SIGALRM is used for different things.
- X *
- X * If you don't want any timeout, #undef it, i.e.,
- X *
- X * #undef TIMEOUT
- X *
- X * TIMEOUT should be at least two hours, which allows users some time
- X * away from their terminal (e.g., at lunch) while reading news.
- X */
- X
- X#ifndef ALONE
- X# define TIMEOUT (2 * 3600)
- X#endif ALONE
- X
- X/*
- X * How long you want nntp servers to wait without receiving data
- X * during article transfers. You CANNOT have XFER_TIMEOUT while
- X * running in standalond (ALONE) mode.
- X *
- X * If you don't want any transfer timeouts, #undef it, as above.
- X */
- X
- X#ifndef ALONE
- X# define XFER_TIMEOUT (30 * 60)
- X#endif ALONE
- X
- X/*
- X * Your domain. This is for the inews generated From: line,
- X * assuming that it doesn't find one in the article's head.
- X * Suggestions are .UUCP if you don't belong to the Internet.
- X * If your hostname returns the fully-qualified domain name
- X * as some 4.3 BSD systems do, simply undefine DOMAIN.
- X *
- X * e.g. #define DOMAIN "berkeley.edu"
- X */
- X
- X#define DOMAIN "uucp"
- X
- X/*
- X * A file containing the name of the host which is running
- X * the news server. This will have to match what rrn thinks,
- X * too.
- X */
- X
- X#define SERVER_FILE "/usr/local/lib/rn/server"
- X
- X/*
- X * Person (user name) to post news as.
- X */
- X
- X#define POSTER "news"
- X
- X/*
- X * These files are generated by the support programs, and are needed
- X * by the NNTP server. Make sure that whatever directory you
- X * decide these files should go is writable by whatever uid you
- X * have the sypport programs run under.
- X */
- X
- X#define STAT_FILE "/usr/lib/news/mgdstats"
- X#define NGDATE_FILE "/usr/lib/news/groupdates"
- X
- X/*
- X * Some commonly used programs and files.
- X */
- X
- X#define ACTIVE_FILE "/usr/lib/news/active"
- X#define ACCESS_FILE "/usr/lib/news/nntp_access"
- X#define HISTORY_FILE "/usr/lib/news/history"
- X#define SPOOLDIR "/usr/spool/news"
- X#define INEWS "/usr/lib/news/inews"
- X#define RNEWS "/usr/bin/rnews" /* Link to inews? */
- X
- X/*
- X * Some miscellaneous stuff you probably don't want to change.
- X */
- X
- X#define MAX_ARTICLES 4096 /* Maximum number of articles/group */
- X#define READINTVL 60 * 10 /* 10 minutes b/n chking active file */
- END_OF_FILE
- if test 5753 -ne `wc -c <'./common/conf.h'`; then
- echo shar: \"'./common/conf.h'\" unpacked with wrong size!
- fi
- # end of './common/conf.h'
- fi
- if test -f './doc/nntpd.dst' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./doc/nntpd.dst'\"
- else
- echo shar: Extracting \"'./doc/nntpd.dst'\" \(5373 characters\)
- sed "s/^X//" >'./doc/nntpd.dst' <<'END_OF_FILE'
- X.\"
- X.\" @(#)nntpd.dst 1.3 (Berkeley) 10/15/87
- X.\"
- X.TH NNTPD 8C "8 July 1987"
- X.UC 4
- X.SH NAME
- nntpd \- Network News Transfer Protocol server
- X.SH SYNOPSIS
- X.B LNNTPD
- X.br
- X.I (with INETD, see below)
- X.SH DESCRIPTION
- X.I Nntpd
- is a server that supports the proposed standard
- for the stream based transmission of network
- news articles.
- It can be used both by ``reader/poster'' clients that
- present news to users, and by
- X``transfer'' clients that transport news between machines.
- When used with Internet TCP,
- X.I nntpd
- operates at the port indicated in the ``nntp'' service
- entry in
- X.IR SERVICES ;
- the port number assigned by the Network Information Center
- for this service is 119.
- For use with DECNET,
- xxx.
- This manual page describes
- X.I nntpd
- from version 1.4 of the NNTP package.
- X.PP
- X.I Nntpd
- can operate either as a stand-alone server, or as a
- server under
- X.IR inetd (1).
- For stand-alone use,
- X.I nntpd
- must be compiled with the -DALONE option, and is
- invoked as mentioned in the synopsis above.
- Under
- X.IR inetd (1),
- the appropriate entry must be made in
- X.IR INETDCONFIG ,
- and the server must be compiled without the
- X-DALONE flag.
- X.PP
- The server handles clients on a one to one basis,
- forking to take care of clients as they request
- connections.
- Each server changes its current
- directory to the news spool directory
- X(
- X.IR NEWSSPOOL )
- and then executes commands from its client.
- These commands are described in ARPA Internet
- RFC 977, ``Network News Transfer Protocol;
- A Proposed Standard for the Stream Based Transmission
- of News Articles.''
- X.SH "CLIENT ACCESS"
- X.PP
- Sites may choose to limit
- the hosts that can query the server for news.
- Further, some sites may not wish to allow
- certain hosts to post news.
- Finally, some sites may wish to restrict the newsgroups
- that can be accessed from remote hosts.
- Such limiting can be accomplished through an
- access file,
- X.IR NEWSLIB/nntp_access .
- This file consists of three or four fields in the following form:
- X.sp
- X.nf
- host/net read/xfer/no post/no newsgroups
- X.fi
- X.sp
- where
- X.f
- X.I host
- is a valid host name as found in
- X.I HOSTFILE,
- X.I net
- is a valid network name as found in
- X.I NETWORKFILE,
- and
- X.I ``read'',
- X.I ``xfer'',
- X.I ``post'',
- and
- X.I ``no''
- are the corresponding string constants.
- X.I Newsgroups
- is an optional list of comma separated newsgroup names.
- Anything to the right of a `#' character
- is taken to be a comment and is ignored.
- X.PP
- The presence of an entry in this file
- implies that specific host, or
- hosts on the named network, are
- allowed to read news, but not to post news.
- The absence of a entry corresponding
- to a client's host or network implies that the client
- is not allowed to read or post news.
- Default permissions can be set by having the
- first entry in the file be a host/net name of
- X``default''.
- If this is used, ``default'' must be the
- first entry.
- X.PP
- The first field to the right of the host/net entry
- specifies the read access of the host/net in
- question.
- If the entry is ``read,'' matching
- hosts can both read and transfer news.
- If the entry is ``xfer,'' however,
- matching hosts can only execute commands
- used for transferring news, such as
- NEWNEWS, NEWGROUPS, IHAVE, and ARTICLE with message-id parameters.
- The string ``no'' denies read permission
- of any kind to a matching host.
- X.PP
- The next field to the right defines
- whether a matching host has post
- permission: if the field is ``post''
- then the POST command is permitted; if
- the field is ``no,'' then matching clients
- are not allowed to post news.
- X.PP
- The next field is optional, and, if present,
- is a comma separated list of newsgroup names
- that restrict the client's reading ability.
- Clients are not allowed to read or transfer
- articles in newsgroup names preceded by an exclamation
- point.
- By default, clients are allowed to read all newsgroups.
- X.PP
- X.I Nntpd
- is selective and searches for a ``best match''
- when searching this file to check its client's
- permissions. That is, a specific host name
- match is used over a
- client being a member of a specified net.
- X.SH EXAMPLE ACCESS FILE
- X.PP
- X.sp
- X.nf
- X#
- X# Example access file
- X#
- default xfer no
- ucb-ether read post
- shadow no no
- ic read post !ucb.postgres
- X.fi
- X.sp
- X.PP
- The above file allows only transfer of news (i.e., no reading or posting)
- by default.
- Hosts on the network ``ucb-ether'' would be able to
- read and post news.
- The host ``shadow'' would not be allowed
- to read or post news.
- Finally, the host ``ic'' is allowed to read and post
- news, but cannot access articles in the newsgroup
- X``ucb.postgres'' or any of its child newsgroups
- X(e.g., ``ucb.postgres.core'').
- X.SH "INFORMING USERS OF NEW NEWSGROUPS"
- X.PP
- The NEWGROUPS command has never worked very well because
- newsgroup creation dates are not stored under
- the USENET news system.
- As a result, it is left to client programs to determine
- by difference in active file size whether new groups exist,
- and if so, whether to inform the user of their existence.
- X.PP
- Older versions of
- X.I nntpd
- relied on the program
- X.I mkgrdates
- to prepare newsgroup creation information.
- X.I Mkgrdates
- was fallible and could present a hefty load
- on the serving system.
- Consequently, it is no longer supported, and its use is discouraged.
- X.SH AUTHOR
- Phil Lapsley (Internet: phil@berkeley.edu; UUCP: ...!ucbvax!phil)
- X.SH SEE ALSO
- services(5),
- inetd(8C)
- X.PP
- RFC 977, ``Network News Transfer Protocol:
- A Proposed Standard for the Stream Based Transmission
- of News Articles.''
- END_OF_FILE
- if test 5373 -ne `wc -c <'./doc/nntpd.dst'`; then
- echo shar: \"'./doc/nntpd.dst'\" unpacked with wrong size!
- fi
- # end of './doc/nntpd.dst'
- fi
- if test -f './doc/nntpxmit.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./doc/nntpxmit.1'\"
- else
- echo shar: Extracting \"'./doc/nntpxmit.1'\" \(5838 characters\)
- sed "s/^X//" >'./doc/nntpxmit.1' <<'END_OF_FILE'
- X.TH NNTPXMIT 1 netnews/NNTP
- X.SH NAME
- X.I nntpxmit
- X\- transmit netnews articles to a remote NNTP server
- X.SH SYNOPSIS
- X.I nntpxmit
- X[
- X.B \-a
- X]
- X[
- X.B \-d
- X]
- X[
- X.B \-s
- X]
- X[
- X.B \-r
- X]
- X[
- X.B \-T
- X]
- X[
- X.B \-F
- X]
- X[
- X.B \-D
- X] hostname|hostname:file [...]
- X.SH DESCRIPTION
- X.PP
- X.I Nntpxmit
- offers netnews articles [RFC850] named in a queue file (a file of
- filenames) to a remote NNTP (Network News Transfer Protocol,
- X[RFC977]) server, transmitting those articles that the remote server
- indicates that it does not already have.
- X.PP
- The command line arguments a processed sequentially, and the flags
- can thus be toggled several times during one invocation of the
- program, by giving the options more than once.
- The options are:
- X.IP hostname|hostname:file
- The name of the remote host, and the name of the queue file of
- articles destined for that host.
- The hostname may be an internet address in dotted
- format (e.g. 10.2.0.78, [10.0.0.78]).
- If the hostname is given without an associated file, it is assumed
- that the hostname is also the name of the queue file.
- If the separator is "::" instead of ":", it is assumed that the
- remote host speaks DECNET, instead of the default, IP/TCP.
- X.IP -s
- Toggles reporting of transfer statistics (how many articles we
- offered them, how many they accepted, etc).
- X.br
- Default is
- X.B ON.
- X.IP -d
- Toggles DEBUG output on stderr.
- This can be used to see exactly what the two systems are saying to
- each other, except for the actual article text.
- X.br
- Default is
- X.B OFF.
- X.IP -r
- Toggles requeuing of failed articles.
- A failed article is an article that we (client) offer them (remote server),
- they accept, we transmit, and then they report that they "failed"
- or dropped the article (i.e. inews(1) on the remote returned non-zero).
- If we have requeuing set, we save the list of articles that they
- failed on, and rewrite the queue file with them, so that they get
- reoffered the next time we initiate transmission to them.
- X.br
- Default is
- X.B ON.
- X.IP -a
- This flag says that the next queue file on the command line isn't
- a queue file, but is a single netnews
- article to be transmitted to the remote in a single operation.
- X.IP
- X.B NOTE:
- this option causes
- X.I nntpxmit
- to exit immediately after this transfer is done (regardless of
- whatever else is on the command line), and to exit with a code
- indicating whether the articles was successfully accepted by the
- remote server (zero exit for success, non-zero for failure).
- X.PP
- The next options set the underlying transport protocol that
- X.I nntpxmit
- uses.
- The NNTP specification assumes a TCP-style transport protocol
- underlies it (i.e. a reliable, flow-controlled, full-duplex byte
- stream).
- X.I Nntpxmit
- assumes that after doing some magic to get a descriptor,
- it can do read(2) and write(2) calls (and use stdio) to move data
- and check for errors.
- By default,
- X.I nntpxmit
- will use IP/TCP (DoD Internet Protocol suite).
- X.IP -T
- Sets transport protocol to IP/TCP for all remaining
- transfers (unless reset by other transport flags).
- Default transport.
- X.IP -D
- Sets transport protocol to DECNET for all remaining
- transfers (unless reset by other transport flags).
- X.B NOTE:
- using "::" as the hostname/queue filename separator has the
- same effect.
- X.IP -F
- This says that the hostname is a file descriptor number, already
- open to a remote server (with some reliable protocol underneath)
- that was passed to
- X.I nntpxmit
- through a fork(2).
- X.SH "THEORY OF OPERATION"
- X.PP
- X.I Nntpxmit
- implements an interactive ihave/sendme transmission system.
- Roughly, the protocol is
- X.IP 1.
- open the article,
- fetch out the message-id (required on all netnews articles),
- and send the command IHAVE <message-id> to the remote.
- X.IP 2.
- The remote will then say either "I've seen it already" or "please send
- that article to me."
- X.IP 3.
- If the response was negative,
- X.I nntpxmit
- loops back to step 1 and offers the next article (until queue file EOF).
- Otherwise,
- X.I nntpxmit
- will send the article, using SMTP [RFC821] text transmission conventions
- X(i.e. CRLF line terminators, and dot escaping).
- X.IP 4.
- X.I Nntpxmit
- waits for the remote to say whether the article was successfully
- accepted or not.
- If the answer is negative and requeuing of failed articles is enabled,
- X.I nntpxmit
- will queue this article's filename to be
- written back to the queue file at the end of the session with this
- remote.
- X.PP
- If the communcation link should fail (and
- X.I nntpxmit
- detects it through a system call error return),
- X.I nntpxmit
- will rewrite the queue file with the article filenames of the
- articles that it did not transmit (that is, we don't retransmit
- stuff we've already successfully sent and gotten back an positive
- confirmation that they got it).
- X.SH FILES
- X/tmp/nntpxmitXXXXXX
- X.SH AUTHOR
- Erik E. Fair
- X.SH "SEE ALSO"
- inews(1),
- X.br
- RFC977 \- Network News Transfer Protocol (NNTP),
- X.br
- RFC850 \- USENET Article Format standard,
- X.br
- RFC821 \- Simple Mail Transfer Protocol (SMTP),
- X.SH BUGS
- X.PP
- Always requeuing failed articles can lead to beating the remote to
- death with a list of articles that he can't accept for come structural
- reason.
- How many of these have to pile up before you should declare that
- something is seriously wrong with the remote system and stop trying?
- X.PP
- While
- X.B nntpxmit
- will lock a queue file (your version of UNIX permitting) against
- multiple invocations of itself, there is no locking with inews(1),
- which is what writes the queue files in the first place.
- Therefore, never use
- X.B nntpxmit
- on the queue files that inews(1) writes, because two processes
- writing into the same file without some kind of cooperation will
- almost certainly trash the file; move them to some other name that
- inews(1) knows nothing about, so that you won't lose articles to
- races between inews and nntpxmit.
- X.PP
- Adding inews(1) compatible locking to the C code would be much more
- trouble than it's worth, and violates the KISS principle besides.
- END_OF_FILE
- if test 5838 -ne `wc -c <'./doc/nntpxmit.1'`; then
- echo shar: \"'./doc/nntpxmit.1'\" unpacked with wrong size!
- fi
- # end of './doc/nntpxmit.1'
- fi
- if test -f './inews/inews.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./inews/inews.c'\"
- else
- echo shar: Extracting \"'./inews/inews.c'\" \(6070 characters\)
- sed "s/^X//" >'./inews/inews.c' <<'END_OF_FILE'
- X#ifndef lint
- static char *sccsid = "@(#)inews.c 1.15 (Berkeley) 2/6/88";
- X#endif
- X
- X/*
- X * Itty-bitty inews for talking to remote server.
- X * Simply accept input on stdin (or via a named file) and dump this
- X * to the server; add a From: and Path: line if missing in the original.
- X * Print meaningful errors from the server.
- X * Limit .signature files to MAX_SIGNATURE lines.
- X * No processing of command line options.
- X *
- X * Original by Steven Grady <grady@ucbvax.Berkeley.EDU>, with thanks from
- X * Phil Lapsley <phil@ucbvax.berkeley.edu>, who is now responsible for it.
- X */
- X
- X#include <stdio.h>
- X#include <pwd.h>
- X#include <ctype.h>
- X#include "../common/conf.h"
- X#include "../common/nntp.h"
- X#ifdef USG
- X#include <string.h>
- X#else not USG
- X#include <strings.h>
- X#endif not USG
- X
- X#define MAX_SIGNATURE 4
- X
- extern FILE *ser_wr_fp;
- X
- char host_name[256];
- X
- main(argc, argv)
- int argc;
- char *argv[];
- X{
- X char line[NNTP_STRLEN], s[NNTP_STRLEN];
- X int seen_fromline, in_header;
- X int response;
- X char *server;
- X char *getserverbyfile();
- X register char *cp;
- X
- X ++argv;
- X while (argc > 1)
- X if (*argv[0] == '-') {
- X ++argv;
- X --argc;
- X } else
- X break;
- X
- X if (argc > 1) {
- X if (freopen(*argv, "r", stdin) == NULL) {
- X perror(*argv);
- X exit(1);
- X }
- X }
- X
- X uname(host_name);
- X
- X server = getserverbyfile(SERVER_FILE);
- X if (server == NULL) {
- X fprintf(stderr,
- X "Can't get the name of the news server from %s.\n",
- X SERVER_FILE);
- X fprintf(stderr,
- X "Either fix this file, or put NNTPSERVER in your enviroment.\n");
- X exit(1);
- X }
- X
- X response = server_init(server);
- X if (response < 0) {
- X printf("Couldn't connect to %s news server, try again later.\n",
- X server);
- X exit(1);
- X }
- X
- X if (handle_server_response(response, server) < 0
- X || response == OK_NOPOST) {
- X close_server();
- X exit(1);
- X }
- X
- X put_server("POST");
- X (void) get_server(line, sizeof(line));
- X if (*line != CHAR_CONT) {
- X if (atoi(line) == ERR_NOPOST) {
- X close_server();
- X fprintf(stderr,
- X "Sorry, you can't post from this machine.\n");
- X exit(1);
- X } else {
- X close_server();
- X fprintf(stderr, "Remote error: %s\n", line);
- X exit(1);
- X }
- X }
- X
- X in_header = 1;
- X seen_fromline = 0;
- X
- X while (gets(s) != NULL) {
- X if (s[0] == '.') /* Single . is eof, so put in extra one */
- X (void) fputc('.', ser_wr_fp);
- X if (in_header && strneql(s, "From:", sizeof("From:")-1))
- X seen_fromline = 1;
- X if (in_header && s[0] == '\0') {
- X in_header = 0;
- X if (!seen_fromline)
- X gen_frompath();
- X }
- X fprintf(ser_wr_fp, "%s\r\n", s);
- X }
- X
- X append_signature();
- X
- X fprintf(ser_wr_fp, ".\r\n");
- X (void) fflush(ser_wr_fp);
- X (void) get_server(line, sizeof(line));
- X if (*line != CHAR_OK) {
- X if (atoi(line) == ERR_POSTFAIL) {
- X close_server();
- X printf("Article not accepted by server; not posted.\n");
- X for (cp = line + 4; *cp && *cp != '\r'; cp++)
- X if (*cp == '\\')
- X putchar('\n');
- X else
- X putchar(*cp);
- X exit(1);
- X } else {
- X close_server();
- X fprintf(stderr, "Remote error: %s\n", line);
- X exit(1);
- X }
- X }
- X
- X /*
- X * Close server sends the server a
- X * "quit" command for us, which is why we don't send it.
- X */
- X
- X close_server();
- X
- X exit(0);
- X}
- X
- X/*
- X * append_signature -- append the person's .signature file if
- X * they have one. Limit .signature to MAX_SIGNATURE lines.
- X */
- X
- append_signature()
- X{
- X char line[256], sigfile[256];
- X char *cp;
- X struct passwd *passwd;
- X FILE *fp;
- X char *index();
- X int count = 0;
- X
- X passwd = getpwuid(getuid());
- X if (passwd == NULL)
- X return;
- X
- X (void) strcpy(sigfile, passwd->pw_dir);
- X (void) strcat(sigfile, "/");
- X (void) strcat(sigfile, ".signature");
- X
- X fp = fopen(sigfile, "r");
- X if (fp == NULL)
- X return;
- X
- X while (fgets(line, sizeof (line), fp)) {
- X count++;
- X if (count > MAX_SIGNATURE) {
- X fprintf(stderr,
- X "Warning: .signature files should be no longer than %d lines.\n",
- X MAX_SIGNATURE);
- X fprintf(stderr,
- X "(Only %d lines of your .signature were posted.)\n",
- X MAX_SIGNATURE);
- X break;
- X }
- X if (cp = index(line, '\n'))
- X *cp = '\0';
- X fprintf(ser_wr_fp, "%s\r\n", line);
- X }
- X (void) fclose(fp);
- X}
- X
- X
- X/*
- X * gen_frompath -- generate From: and Path: lines, in the form
- X *
- X * From: user@host.domain (full_name)
- X * Path: host!user
- X *
- X * This routine should only be called if the message doesn't have
- X * a From: line in it.
- X */
- X
- gen_frompath()
- X{
- X char *full_name;
- X char *cp;
- X struct passwd *passwd;
- X char *index(), *getenv();
- X
- X passwd = getpwuid(getuid());
- X
- X full_name = getenv("NAME");
- X if (full_name == NULL) {
- X full_name = passwd->pw_gecos;
- X if ((cp = index(full_name, ',')))
- X *cp = '\0';
- X }
- X
- X#ifdef DOMAIN
- X
- X /* A heuristic to see if we should tack on a domain */
- X
- X cp = index(host_name, '.');
- X if (cp)
- X fprintf(ser_wr_fp, "From: %s@%s (",
- X passwd->pw_name,
- X host_name);
- X else
- X fprintf(ser_wr_fp, "From: %s@%s.%s (",
- X passwd->pw_name,
- X host_name,
- X DOMAIN);
- X#else
- X fprintf(ser_wr_fp, "From: %s@%s (",
- X passwd->pw_name,
- X host_name);
- X#endif
- X
- X for (cp = full_name; *cp != '\0'; ++cp)
- X if (*cp != '&')
- X putc(*cp, ser_wr_fp);
- X else { /* Stupid & hack. God damn it. */
- X putc(toupper(passwd->pw_name[0]), ser_wr_fp);
- X fprintf(ser_wr_fp, passwd->pw_name+1);
- X }
- X
- X fprintf(ser_wr_fp, ")\r\n");
- X
- X fprintf(ser_wr_fp, "Path: %s!%s\r\n", host_name, passwd->pw_name);
- X}
- X
- X
- X/*
- X * strneql -- determine if two strings are equal in the first n
- X * characters, ignoring case.
- X *
- X * Parameters: "a" and "b" are the pointers
- X * to characters to be compared.
- X * "n" is the number of characters to compare.
- X *
- X * Returns: 1 if the strings are equal, 0 otherwise.
- X *
- X * Side effects: None.
- X */
- X
- strneql(a, b, n)
- register char *a, *b;
- int n;
- X{
- X char lower();
- X
- X while (n && lower(*a) == lower(*b)) {
- X if (*a == '\0')
- X return (1);
- X a++;
- X b++;
- X n--;
- X }
- X if (n)
- X return (0);
- X else
- X return (1);
- X}
- X
- X/*
- X * lower -- convert a character to lower case, if it's
- X * upper case.
- X *
- X * Parameters: "c" is the character to be
- X * converted.
- X *
- X * Returns: "c" if the character is not
- X * upper case, otherwise the lower
- X * case eqivalent of "c".
- X *
- X * Side effects: None.
- X */
- X
- char lower(c)
- register char c;
- X{
- X if (isascii(c) && isupper(c))
- X c = c - 'A' + 'a';
- X return(c);
- X}
- END_OF_FILE
- if test 6070 -ne `wc -c <'./inews/inews.c'`; then
- echo shar: \"'./inews/inews.c'\" unpacked with wrong size!
- fi
- # end of './inews/inews.c'
- fi
- if test -f './rrnpatches/newsetup.SH.pat' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./rrnpatches/newsetup.SH.pat'\"
- else
- echo shar: Extracting \"'./rrnpatches/newsetup.SH.pat'\" \(4675 characters\)
- sed "s/^X//" >'./rrnpatches/newsetup.SH.pat' <<'END_OF_FILE'
- X*** rn/newsetup.SH Sun Mar 15 19:54:40 1987
- X--- rrn/newsetup.SH Thu Feb 25 20:35:26 1988
- X***************
- X*** 1,5
- X case $CONFIG in
- X! '') . config.sh ;;
- X esac
- X echo "Extracting newsetup (with variable substitutions)"
- X $spitshell >newsetup <<!GROK!THIS!
- X
- X--- 1,5 -----
- X case $CONFIG in
- X! '') . ./config.sh ;;
- X esac
- X echo "Extracting newsetup (with variable substitutions)"
- X $spitshell >newsetup <<!GROK!THIS!
- X***************
- X*** 32,38
- X state="$statepref"
- X cntry="$cntrypref"
- X cont="$contpref"
- X! active="${active-/usr/lib/news/active}"
- X
- X dotdir="\${DOTDIR-\${HOME-\$LOGDIR}}"
- X $rm -f \$dotdir/.oldnewsrc
- X
- X--- 32,38 -----
- X state="$statepref"
- X cntry="$cntrypref"
- X cont="$contpref"
- X! active="/tmp/active.\$\$"
- X
- X dotdir="\${DOTDIR-\${HOME-\$LOGDIR}}"
- X $rm -f \$dotdir/.oldnewsrc
- X***************
- X*** 38,46
- X $rm -f \$dotdir/.oldnewsrc
- X $echo "Creating .newsrc in \$dotdir to be used by news programs."
- X
- X! case \$active in
- X! ~*) active=\`$filexp \$active\` ;;
- X! esac
- X
- X : NOTE: SED WILL NOT TAKE MORE THAN 10 WFILES, SO BEWARE
- X
- X
- X--- 38,44 -----
- X $rm -f \$dotdir/.oldnewsrc
- X $echo "Creating .newsrc in \$dotdir to be used by news programs."
- X
- X! $rnlib/getactive \$active
- X
- X : NOTE: SED WILL NOT TAKE MORE THAN 10 WFILES, SO BEWARE
- X
- X***************
- X*** 58,71
- X -e " w /tmp/n.test\$\$" \\
- X -e ' d' \\
- X -e '}' \\
- X- -e "/^net\./{" \\
- X- -e " w /tmp/n.net\$\$" \\
- X- -e ' d' \\
- X- -e '}' \\
- X- -e "/^mod\./{" \\
- X- -e " w /tmp/n.mod\$\$" \\
- X- -e ' d' \\
- X- -e '}' \\
- X -e "/^\$locorg\./{" \\
- X -e " w /tmp/n.\$locorg\$\$" \\
- X -e ' d' \\
- X
- X--- 56,61 -----
- X -e " w /tmp/n.test\$\$" \\
- X -e ' d' \\
- X -e '}' \\
- X -e "/^\$locorg\./{" \\
- X -e " w /tmp/n.\$locorg\$\$" \\
- X -e ' d' \\
- X***************
- X*** 78,83
- X -e " w /tmp/n.\$city\$\$" \\
- X -e ' d' \\
- X -e '}' \\
- X -e "/^\$state\./{" \\
- X -e " w /tmp/n.\$state\$\$" \\
- X -e ' d' \\
- X
- X--- 68,77 -----
- X -e " w /tmp/n.\$city\$\$" \\
- X -e ' d' \\
- X -e '}' \\
- X+ -e "/^\$cntry\./{" \\
- X+ -e " w /tmp/n.\$cntry\$\$" \\
- X+ -e ' d' \\
- X+ -e '}' \\
- X -e "/^\$state\./{" \\
- X -e " w /tmp/n.\$state\$\$" \\
- X -e ' d' \\
- X***************
- X*** 81,90
- X -e "/^\$state\./{" \\
- X -e " w /tmp/n.\$state\$\$" \\
- X -e ' d' \\
- X- -e '}' \\
- X- -e "/^fa\./{" \\
- X- -e " w /tmp/n.fa\$\$" \\
- X- -e ' d' \\
- X -e '}'
- X
- X $sed </tmp/n.tmp\$\$ >/tmp/n.local\$\$ \\
- X
- X--- 75,80 -----
- X -e "/^\$state\./{" \\
- X -e " w /tmp/n.\$state\$\$" \\
- X -e ' d' \\
- X -e '}'
- X
- X $sed </tmp/n.tmp\$\$ >/tmp/n.local\$\$ \\
- X***************
- X*** 88,97
- X -e '}'
- X
- X $sed </tmp/n.tmp\$\$ >/tmp/n.local\$\$ \\
- X- -e "/^\$cntry\./{" \\
- X- -e " w /tmp/n.\$cntry\$\$" \\
- X- -e ' d' \\
- X- -e '}' \\
- X -e "/^\$cont\./{" \\
- X -e " w /tmp/n.\$cont\$\$" \\
- X -e ' d' \\
- X
- X--- 78,83 -----
- X -e '}'
- X
- X $sed </tmp/n.tmp\$\$ >/tmp/n.local\$\$ \\
- X -e "/^\$cont\./{" \\
- X -e " w /tmp/n.\$cont\$\$" \\
- X -e ' d' \\
- X***************
- X*** 144,150
- X /tmp/n.\$state\$\$ \\
- X /tmp/n.\$cntry\$\$ \\
- X /tmp/n.\$cont\$\$ \\
- X- /tmp/n.mod\$\$ \\
- X /tmp/n.news\$\$ \\
- X /tmp/n.comp\$\$ \\
- X /tmp/n.sci\$\$ \\
- X
- X--- 130,135 -----
- X /tmp/n.\$state\$\$ \\
- X /tmp/n.\$cntry\$\$ \\
- X /tmp/n.\$cont\$\$ \\
- X /tmp/n.news\$\$ \\
- X /tmp/n.comp\$\$ \\
- X /tmp/n.sci\$\$ \\
- X***************
- X*** 152,159
- X /tmp/n.soc\$\$ \\
- X /tmp/n.misc\$\$ \\
- X /tmp/n.talk\$\$ \\
- X- /tmp/n.net\$\$ \\
- X- /tmp/n.fa\$\$ \\
- X /tmp/n.test\$\$ \\
- X | $uniq >\$dotdir/.newsrc
- X
- X
- X--- 137,142 -----
- X /tmp/n.soc\$\$ \\
- X /tmp/n.misc\$\$ \\
- X /tmp/n.talk\$\$ \\
- X /tmp/n.test\$\$ \\
- X | $uniq >\$dotdir/.newsrc
- X
- X***************
- X*** 166,172
- X /tmp/n.\$state\$\$ \\
- X /tmp/n.\$cntry\$\$ \\
- X /tmp/n.\$cont\$\$ \\
- X- /tmp/n.mod\$\$ \\
- X /tmp/n.news\$\$ \\
- X /tmp/n.comp\$\$ \\
- X /tmp/n.sci\$\$ \\
- X
- X--- 149,154 -----
- X /tmp/n.\$state\$\$ \\
- X /tmp/n.\$cntry\$\$ \\
- X /tmp/n.\$cont\$\$ \\
- X /tmp/n.news\$\$ \\
- X /tmp/n.comp\$\$ \\
- X /tmp/n.sci\$\$ \\
- X***************
- X*** 173,180
- X /tmp/n.soc\$\$ \\
- X /tmp/n.rec\$\$ \\
- X /tmp/n.talk\$\$ \\
- X- /tmp/n.net\$\$ \\
- X- /tmp/n.fa\$\$ \\
- X /tmp/n.misc\$\$ \\
- X /tmp/n.test\$\$
- X
- X
- X--- 155,160 -----
- X /tmp/n.soc\$\$ \\
- X /tmp/n.rec\$\$ \\
- X /tmp/n.talk\$\$ \\
- X /tmp/n.misc\$\$ \\
- X /tmp/n.test\$\$ \\
- X \$active
- X***************
- X*** 176,182
- X /tmp/n.net\$\$ \\
- X /tmp/n.fa\$\$ \\
- X /tmp/n.misc\$\$ \\
- X! /tmp/n.test\$\$
- X
- X $cat <<'EOH'
- X Done.
- X
- X--- 156,163 -----
- X /tmp/n.rec\$\$ \\
- X /tmp/n.talk\$\$ \\
- X /tmp/n.misc\$\$ \\
- X! /tmp/n.test\$\$ \\
- X! \$active
- X
- X $cat <<'EOH'
- X Done.
- END_OF_FILE
- if test 4675 -ne `wc -c <'./rrnpatches/newsetup.SH.pat'`; then
- echo shar: \"'./rrnpatches/newsetup.SH.pat'\" unpacked with wrong size!
- fi
- # end of './rrnpatches/newsetup.SH.pat'
- fi
- if test -f './rrnpatches/ng.c.pat' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./rrnpatches/ng.c.pat'\"
- else
- echo shar: Extracting \"'./rrnpatches/ng.c.pat'\" \(5064 characters\)
- sed "s/^X//" >'./rrnpatches/ng.c.pat' <<'END_OF_FILE'
- X*** rn/ng.c Sun Mar 15 19:54:26 1987
- X--- rrn/ng.c Mon May 25 22:41:53 1987
- X***************
- X*** 48,53
- X #include "rcln.h"
- X #include "last.h"
- X #include "search.h"
- X #include "INTERN.h"
- X #include "ng.h"
- X #include "artstate.h" /* somebody has to do it */
- X
- X--- 48,54 -----
- X #include "rcln.h"
- X #include "last.h"
- X #include "search.h"
- X+ #include "server.h"
- X #include "INTERN.h"
- X #include "ng.h"
- X #include "artstate.h" /* somebody has to do it */
- X***************
- X*** 110,115
- X do_newsgroup(start_command)
- X char *start_command; /* command to fake up first */
- X {
- X char oldmode = mode;
- X register long i; /* scratch */
- X int skipstate; /* how many unavailable articles */
- X
- X--- 111,121 -----
- X do_newsgroup(start_command)
- X char *start_command; /* command to fake up first */
- X {
- X+ #ifdef SERVER
- X+ char ser_line[256];
- X+ char artname[32];
- X+ static long our_pid;
- X+ #endif SERVER
- X char oldmode = mode;
- X register long i; /* scratch */
- X int skipstate; /* how many unavailable articles */
- X***************
- X*** 117,122
- X
- X char *whatnext = "%sWhat next? [%s]";
- X
- X #ifdef ARTSEARCH
- X srchahead = (scanon && ((ART_NUM)toread[ng]) >= scanon ? -1 : 0);
- X /* did they say -S? */
- X
- X--- 123,133 -----
- X
- X char *whatnext = "%sWhat next? [%s]";
- X
- X+ #ifdef SERVER
- X+ if (our_pid == 0) /* Agreed, this is gross */
- X+ our_pid = getpid();
- X+ #endif SERVER
- X+
- X #ifdef ARTSEARCH
- X srchahead = (scanon && ((ART_NUM)toread[ng]) >= scanon ? -1 : 0);
- X /* did they say -S? */
- X***************
- X*** 125,130
- X mode = 'a';
- X recent_art = curr_art = 0;
- X exit_code = NG_NORM;
- X if (eaccess(ngdir,5)) { /* directory read protected? */
- X if (eaccess(ngdir,0)) {
- X #ifdef VERBOSE
- X
- X--- 136,156 -----
- X mode = 'a';
- X recent_art = curr_art = 0;
- X exit_code = NG_NORM;
- X+
- X+ #ifdef SERVER
- X+ sprintf(ser_line, "GROUP %s", ngname);
- X+ put_server(ser_line);
- X+ if (get_server(ser_line, sizeof(ser_line)) < 0) {
- X+ fprintf(stderr, "rrn: Unexpected close of server socket.\n");
- X+ finalize(1);
- X+ }
- X+ if (*ser_line != CHAR_OK) {
- X+ if (atoi(ser_line) != ERR_NOGROUP)
- X+ fprintf(stderr, "rrn: server response to GROUP %s:\n%s\n",
- X+ ngname, ser_line);
- X+ return (-1);
- X+ }
- X+ #else not SERVER
- X if (eaccess(ngdir,5)) { /* directory read protected? */
- X if (eaccess(ngdir,0)) {
- X #ifdef VERBOSE
- X***************
- X*** 165,170
- X mode = oldmode;
- X return -1;
- X }
- X
- X #ifdef CACHESUBJ
- X subj_list = Null(char **); /* no subject list till needed */
- X
- X--- 191,197 -----
- X mode = oldmode;
- X return -1;
- X }
- X+ #endif SERVER
- X
- X #ifdef CACHESUBJ
- X subj_list = Null(char **); /* no subject list till needed */
- X***************
- X*** 293,298
- X else if
- X (!reread && !was_read(art)
- X && artopen(art) == Nullfp) { /* never read it, & cannot find it? */
- X if (errno != ENOENT) { /* has it not been deleted? */
- X #ifdef VERBOSE
- X IF(verbose)
- X
- X--- 320,326 -----
- X else if
- X (!reread && !was_read(art)
- X && artopen(art) == Nullfp) { /* never read it, & cannot find it? */
- X+ #ifndef SERVER
- X if (errno != ENOENT) { /* has it not been deleted? */
- X #ifdef VERBOSE
- X IF(verbose)
- X***************
- X*** 306,311
- X skipstate = 0;
- X sleep(2);
- X }
- X switch(skipstate++) {
- X case 0:
- X clear();
- X
- X--- 334,340 -----
- X skipstate = 0;
- X sleep(2);
- X }
- X+ #endif
- X switch(skipstate++) {
- X case 0:
- X clear();
- X***************
- X*** 329,334
- X default:
- X putchar('.');
- X fflush(stdout);
- X #define READDIR
- X #ifdef READDIR
- X { /* fast skip patch */
- X
- X--- 358,364 -----
- X default:
- X putchar('.');
- X fflush(stdout);
- X+ #ifndef SERVER
- X #define READDIR
- X #ifdef READDIR
- X { /* fast skip patch */
- X***************
- X*** 341,346
- X art = newart - 1;
- X }
- X #endif
- X break;
- X }
- X oneless(art); /* mark deleted as read */
- X
- X--- 371,396 -----
- X art = newart - 1;
- X }
- X #endif
- X+ #else
- X+ {
- X+ char ser_line[256];
- X+ ART_NUM newart;
- X+
- X+ put_server("NEXT");
- X+ if (get_server(ser_line, sizeof (ser_line)) < 0) {
- X+ fprintf(stderr,
- X+ "rrn: unexpected close of server socket.\n");
- X+ finalize(1);
- X+ }
- X+ if (ser_line[0] != CHAR_OK)
- X+ newart = lastart + 1;
- X+ else
- X+ newart = atoi(ser_line+4);
- X+ for (i=art; i<newart; i++)
- X+ oneless(i);
- X+ art = newart - 1;
- X+ }
- X+ #endif SERVER
- X break;
- X }
- X oneless(art); /* mark deleted as read */
- X***************
- X*** 450,455
- X if (artfp != Nullfp) { /* article still open? */
- X fclose(artfp); /* close it */
- X artfp = Nullfp; /* and tell the world */
- X openart = 0;
- X }
- X putchar('\n') FLUSH;
- X
- X--- 500,509 -----
- X if (artfp != Nullfp) { /* article still open? */
- X fclose(artfp); /* close it */
- X artfp = Nullfp; /* and tell the world */
- X+ #ifdef SERVER
- X+ sprintf(artname, "/tmp/rrn%ld.%ld", (long) openart, our_pid);
- X+ UNLINK(artname);
- X+ #endif SERVER
- X openart = 0;
- X }
- X putchar('\n') FLUSH;
- END_OF_FILE
- if test 5064 -ne `wc -c <'./rrnpatches/ng.c.pat'`; then
- echo shar: \"'./rrnpatches/ng.c.pat'\" unpacked with wrong size!
- fi
- # end of './rrnpatches/ng.c.pat'
- fi
- if test -f './server/netaux.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./server/netaux.c'\"
- else
- echo shar: Extracting \"'./server/netaux.c'\" \(4765 characters\)
- sed "s/^X//" >'./server/netaux.c' <<'END_OF_FILE'
- X#ifndef lint
- static char *sccsid = "@(#)netaux.c 1.11 (Berkeley) 2/25/88";
- X#endif
- X
- X/*
- X * Routines to deal with network stuff for
- X * stand-alone version of server.
- X */
- X
- X#include "common.h"
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#ifndef EXCELAN
- X#include <netdb.h>
- X#endif not EXCELAN
- X#include <sys/ioctl.h>
- X#include <signal.h>
- X#ifdef USG
- X#include <time.h>
- X#else not USG
- X#include <sys/time.h>
- X#endif USG
- X
- X#ifdef ALONE
- X
- X
- X/*
- X * disassociate this process from the invoker's terminal.
- X * Close all file descriptors, and then open 0, 1, and 2 to
- X * somewhere bogus (i.e., "/", O_RDONLY). This way we will know
- X * that stdin/out/err will at least be claimed.
- X *
- X * Parameters: None.
- X *
- X * Returns: Nothing.
- X *
- X * Side effects: Disassociates this process from
- X * a terminal; closes file descriptors;
- X * fd 0-2 opened as O_RDONLY to /.
- X */
- X
- disassoc()
- X{
- X register int i;
- X
- X#ifdef USG
- X (void) signal(SIGTERM, SIG_IGN);
- X (void) signal(SIGINT, SIG_IGN);
- X (void) signal(SIGQUIT, SIG_IGN);
- X#endif
- X
- X if (fork())
- X exit(0);
- X
- X for (i = 0; i < 10; i++)
- X (void) close(i);
- X
- X#ifdef USG
- X (void) open("/", 0);
- X (void) dup2(0, 1);
- X (void) dup2(0, 2);
- X setpgrp();
- X umask(000);
- X#else not USG
- X i = open("/dev/tty", O_RDWR);
- X if (i >= 0) {
- X ioctl(i, TIOCNOTTY, 0);
- X (void) close(i);
- X }
- X
- X i = open("/", O_RDONLY);
- X if (i >= 0) {
- X if (i != 0) { /* should never happen */
- X (void) dup2(i, 0);
- X (void) close(i);
- X }
- X (void) dup2(0, 1);
- X (void) dup2(1, 2);
- X }
- X#endif not USG
- X}
- X
- X
- X/*
- X * get_socket -- create a socket bound to the appropriate
- X * port number.
- X *
- X * Parameters: None.
- X *
- X * Returns: Socket bound to correct address.
- X *
- X * Side effects: None.
- X *
- X * Errors: Syslogd, cause aboriton.
- X */
- X
- get_socket()
- X{
- X int s;
- X struct sockaddr_in sin;
- X#ifndef EXCELAN
- X struct servent *sp;
- X
- X sp = getservbyname("nntp", "tcp");
- X if (sp == NULL) {
- X#ifdef SYSLOG
- X syslog(LOG_ERR, "get_socket: tcp/nntp, unknown service.");
- X#endif
- X exit(1);
- X }
- X#endif not EXCELAN
- X
- X bzero((char *) &sin, sizeof (sin));
- X sin.sin_family = AF_INET;
- X sin.sin_addr.s_addr = htonl(INADDR_ANY);
- X#ifndef EXCELAN
- X sin.sin_port = sp->s_port;
- X
- X s = socket(AF_INET, SOCK_STREAM, 0);
- X#else EXCELAN
- X sin.sin_port = htons(IPPORT_NNTP);
- X s = 3; /* WTF??? */
- X s = socket(SOCK_STREAM, (struct sockproto *)0, &sin,
- X (SO_KEEPALIVE|SO_ACCEPTCONN));
- X#endif EXCELAN
- X if (s < 0) {
- X#ifdef EXCELAN
- X sleep(5);
- X return (-1);
- X#else not EXCELAN
- X#ifdef SYSLOG
- X syslog(LOG_ERR, "get_socket: socket: %m");
- X#endif SYSLOG
- X exit(1);
- X#endif not EXCELAN
- X }
- X
- X#ifndef EXCELAN
- X if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
- X#ifdef SYSLOG
- X syslog(LOG_ERR, "get_socket: bind: %m");
- X#endif
- X exit(1);
- X }
- X#endif not EXCELAN
- X
- X return (s);
- X}
- X
- X/*
- X * make_stdio -- make a given socket be our standard input
- X * and output.
- X *
- X * Parameters: "sockt" is the socket we want to
- X * be file descriptors 0, 1, and 2.
- X *
- X * Returns: Nothing.
- X *
- X * Side effects: None.
- X */
- X
- make_stdio(sockt)
- X int sockt;
- X{
- X if (sockt != 0) {
- X (void) dup2(sockt, 0);
- X (void) close(sockt);
- X }
- X (void) dup2(0, 1);
- X (void) dup2(1, 2);
- X}
- X
- X/*
- X * set_timer -- set up the interval timer so that
- X * the active file is read in every so often.
- X *
- X * Parameters: None.
- X *
- X * Returns: Nothing.
- X *
- X * Side effects: Sets interval timer to READINTVL seconds.
- X * Sets SIGALRM to call read_again.
- X */
- X
- set_timer()
- X{
- X#ifndef USG
- X struct itimerval new, old;
- X#endif not USG
- X extern int read_again();
- X
- X (void) signal(SIGALRM, read_again);
- X#ifdef USG
- X alarm(READINTVL);
- X#else not USG
- X
- X new.it_value.tv_sec = READINTVL;
- X new.it_value.tv_usec = 0;
- X new.it_interval.tv_sec = READINTVL;
- X new.it_interval.tv_usec = 0;
- X old.it_value.tv_sec = 0;
- X old.it_value.tv_usec = 0;
- X old.it_interval.tv_sec = 0;
- X old.it_interval.tv_usec = 0;
- X
- X if (setitimer(ITIMER_REAL, &new, &old) < 0) {
- X#ifdef SYSLOG
- X syslog(LOG_ERR, "set_timer: setitimer: %m\n");
- X#endif SYSLOG
- X exit(1);
- X }
- X#endif not USG
- X}
- X
- X
- X/*
- X * read_again -- (maybe) read in the active file again,
- X * if it's changed since the last time we checked.
- X *
- X * Parameters: None (called by interrupt).
- X *
- X * Returns: Nothing.
- X *
- X * Side effects: May change "num_groups" and "group_array".
- X */
- X
- read_again()
- X{
- X static long last_mtime; /* Last time active file was changed */
- X struct stat statbuf;
- X
- X if (stat(activefile, &statbuf) < 0)
- X return;
- X
- X if (statbuf.st_mtime != last_mtime) {
- X last_mtime = statbuf.st_mtime;
- X num_groups = read_groups();
- X }
- X}
- X
- X
- X/*
- X * reaper -- reap children who are ready to die.
- X * Called by signal.
- X *
- X * Parameters: None.
- X *
- X * Returns: Nothing.
- X *
- X * Side effects: None.
- X */
- X
- reaper()
- X{
- X#ifndef USG
- X union wait status;
- X
- X while (wait3(&status, WNOHANG, (struct rusage *)0) > 0)
- X ;
- X#endif not USG
- X}
- X
- X#else not ALONE
- X
- X/* Kludge for greenhill's C compiler */
- X
- static
- netaux_greenkludge()
- X{
- X}
- X#endif not ALONE
- END_OF_FILE
- if test 4765 -ne `wc -c <'./server/netaux.c'`; then
- echo shar: \"'./server/netaux.c'\" unpacked with wrong size!
- fi
- # end of './server/netaux.c'
- fi
- if test -f './server/spawn.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./server/spawn.c'\"
- else
- echo shar: Extracting \"'./server/spawn.c'\" \(5169 characters\)
- sed "s/^X//" >'./server/spawn.c' <<'END_OF_FILE'
- X#ifndef lint
- static char *sccsid = "@(#)spawn.c 1.6 (Berkeley) 2/6/88";
- X#endif
- X
- X#include "../common/conf.h"
- X
- X#include "common.h"
- X
- X#include <signal.h>
- X
- X#ifdef XFER_TIMEOUT
- static int xfer_lines;
- static int old_xfer_lines;
- X#endif
- X
- static char tempfile[256];
- X
- X/*
- X * spawn -- create a child process with the input from the client
- X * as stdin.
- X *
- X * Parameters: "path" is the path of the program to invoke.
- X * "name" is the name to call the program.
- X * "flag" is a single flag to be passed to the program.
- X * "cont_code" is the response code to transmit
- X * on successful startup.
- X * "err_code" is the response code to transmit when
- X * something goes wrong.
- X *
- X * Returns: -1 on non-zero return from child,
- X * 0 on error before fork/exec,
- X * 1 otherwise.
- X *
- X * Side effects: Creates and removes temporary file;
- X * accepts input from client; forks and execs.
- X * Can time out if XFER_TIMEOUT is defined.
- X */
- X
- spawn(path, name, flag, cont_code, err_code, errbuf)
- X char *path;
- X char *name;
- X char *flag;
- X int cont_code;
- X int err_code;
- X char *errbuf;
- X{
- X char line[NNTP_STRLEN];
- X register char *cp;
- X int i, fd;
- X int fds[2];
- X int pid, npid;
- X int exit_status;
- X#ifdef XFER_TIMEOUT
- X int xfer_timeout();
- X int (*otimeout)();
- X#endif
- X#ifdef USG
- X int status;
- X#else not USG
- X union wait status;
- X#endif not USG
- X register FILE *fp;
- X
- X (void) strcpy(tempfile, "/tmp/rpostXXXXXX");
- X (void) mktemp(tempfile);
- X
- X fp = fopen(tempfile, "w");
- X if (fp == NULL) {
- X printf("%d Cannot create temporary file.\r\n", err_code);
- X (void) fflush(stdout);
- X return (0);
- X } else {
- X printf("%d Ok\r\n", cont_code);
- X (void) fflush(stdout);
- X }
- X
- X#ifdef XFER_TIMEOUT
- X xfer_lines = old_xfer_lines = 0;
- X otimeout = signal(SIGALRM, xfer_timeout);
- X (void) alarm(XFER_TIMEOUT);
- X#endif
- X
- X while (fgets(line, sizeof(line), stdin) != NULL) {
- X#ifdef XFER_TIMEOUT
- X xfer_lines++;
- X#endif
- X if ((cp = index(line, '\r')) != NULL)
- X *cp = '\0';
- X else if ((cp = index(line, '\n')) != NULL)
- X *cp = '\0';
- X
- X if (line[0] == '.' && line[1] == '\0')
- X break;
- X
- X if (line[0] == '.')
- X fputs(line+1, fp);
- X else
- X fputs(line, fp);
- X putc('\n', fp);
- X }
- X (void) fclose(fp);
- X
- X#ifdef XFER_TIMEOUT
- X (void) alarm(0);
- X (void) signal(SIGALRM, otimeout);
- X#endif
- X
- X /* See if the connection got closed somehow... */
- X
- X if (line[0] != '.' && line[1] != '\0') {
- X (void) unlink(tempfile);
- X#ifdef SYSLOG
- X# ifdef LOG
- X syslog(LOG_ERR, "%s spawn: EOF before period on line by itself",
- X hostname);
- X# else
- X syslog(LOG_ERR, "spawn: EOF before period on line by itself");
- X# endif
- X#endif
- X return (0);
- X }
- X
- X#ifdef POSTER
- X (void) chown(tempfile, uid_poster, gid_poster);
- X#endif
- X
- X /* Set up a pipe so we can see errors from rnews */
- X
- X if (pipe(fds) < 0) {
- X#ifdef SYSLOG
- X syslog(LOG_ERR, "spawn: pipe: %m");
- X#endif
- X (void) unlink(tempfile);
- X return (-1);
- X }
- X
- X /*
- X * Ok, now we have the article in "tempfile". We
- X * should be able to fork off, close fd's 0 to 31 (or
- X * whatever), open "tempfile" for input, thus making
- X * it stdin, and then execl the inews. We think.
- X */
- X
- X pid = vfork();
- X if (pid == 0) { /* We're in child */
- X#ifdef POSTER
- X (void) setuid(uid_poster);
- X (void) setgid(gid_poster);
- X#endif
- X
- X /* Set up stdout and stderr for child */
- X
- X if (fds[1] != 1) {
- X (void) dup2(fds[1], 1);
- X (void) close(fds[1]);
- X }
- X (void) dup2(1, 2);
- X
- X for (i = 3; i < 10; ++i) /* XXX but getdtablesize is too big */
- X (void) close(i);
- X
- X fd = open(tempfile, O_RDONLY);
- X if (fd != 0) {
- X (void) dup2(fd, 0);
- X (void) close(fd);
- X }
- X
- X execl(path, name, flag, (char *) NULL);
- X fprintf(stderr, "spawn: execl ");
- X perror(path);
- X _exit(-1); /* Error */
- X } else {
- X (void) close(fds[1]);
- X fp = fdopen(fds[0], "r");
- X if (fp == NULL) {
- X printf("%d Cannot fdopen %s pipe\r\n", err_code, path);
- X (void) fflush(stdout);
- X#ifdef SYSLOG
- X syslog(LOG_ERR, "spawn: pipe: %m");
- X#endif
- X (void) unlink(tempfile);
- X return (0);
- X }
- X
- X if (errbuf)
- X *errbuf = '\0';
- X
- X while (fgets(line, sizeof (line), fp) != NULL) {
- X if (line[0] != '\n') {
- X if (errbuf) {
- X if (cp = index(line, '\n'))
- X *cp = '\0';
- X (void) strcat(errbuf, line);
- X (void) strcat(errbuf, "\\");
- X }
- X#ifdef SYSLOG
- X syslog(LOG_ERR, "%s: %s", path, line);
- X#endif
- X }
- X }
- X
- X while ((npid = wait(&status)) > 0)
- X if (npid == pid) {
- X#ifdef USG
- X exit_status = (status >> 8) & 0xff;
- X#else not USG
- X exit_status = status.w_T.w_Retcode;
- X#endif not USG
- X break;
- X }
- X
- X (void) fclose(fp);
- X (void) unlink(tempfile);
- X (void) fflush(stdout);
- X if (npid < 0) {
- X#ifdef SYSLOG
- X syslog(LOG_ERR, "spawn: wait pid %d: %m", pid);
- X#endif
- X return (-1);
- X }
- X
- X#ifdef SYSLOG
- X if (exit_status != 0)
- X syslog(LOG_ERR, "spawn: %s exit status %d",
- X path, exit_status);
- X#endif
- X
- X return (exit_status ? -1 : 1);
- X }
- X}
- X
- X#ifdef XFER_TIMEOUT
- X
- xfer_timeout()
- X{
- X if (old_xfer_lines < xfer_lines) {
- X old_xfer_lines = xfer_lines;
- X (void) alarm(XFER_TIMEOUT);
- X return;
- X }
- X
- X /* Timed out. */
- X
- X printf("%d timeout after %d seconds, closing connection.\r\n",
- X ERR_FAULT, XFER_TIMEOUT);
- X fflush(stdout);
- X
- X#ifdef LOG
- X syslog(LOG_ERR, "%s transfer_timeout", hostname);
- X#endif LOG
- X
- X (void) unlink(tempfile);
- X
- X exit(1);
- X}
- X
- X#endif XFER_TIMEOUT
- END_OF_FILE
- if test 5169 -ne `wc -c <'./server/spawn.c'`; then
- echo shar: \"'./server/spawn.c'\" unpacked with wrong size!
- fi
- # end of './server/spawn.c'
- fi
- if test -f './xmit/nntpxmit.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./xmit/nntpxmit.1'\"
- else
- echo shar: Extracting \"'./xmit/nntpxmit.1'\" \(5838 characters\)
- sed "s/^X//" >'./xmit/nntpxmit.1' <<'END_OF_FILE'
- X.TH NNTPXMIT 1 netnews/NNTP
- X.SH NAME
- X.I nntpxmit
- X\- transmit netnews articles to a remote NNTP server
- X.SH SYNOPSIS
- X.I nntpxmit
- X[
- X.B \-a
- X]
- X[
- X.B \-d
- X]
- X[
- X.B \-s
- X]
- X[
- X.B \-r
- X]
- X[
- X.B \-T
- X]
- X[
- X.B \-F
- X]
- X[
- X.B \-D
- X] hostname|hostname:file [...]
- X.SH DESCRIPTION
- X.PP
- X.I Nntpxmit
- offers netnews articles [RFC850] named in a queue file (a file of
- filenames) to a remote NNTP (Network News Transfer Protocol,
- X[RFC977]) server, transmitting those articles that the remote server
- indicates that it does not already have.
- X.PP
- The command line arguments a processed sequentially, and the flags
- can thus be toggled several times during one invocation of the
- program, by giving the options more than once.
- The options are:
- X.IP hostname|hostname:file
- The name of the remote host, and the name of the queue file of
- articles destined for that host.
- The hostname may be an internet address in dotted
- format (e.g. 10.2.0.78, [10.0.0.78]).
- If the hostname is given without an associated file, it is assumed
- that the hostname is also the name of the queue file.
- If the separator is "::" instead of ":", it is assumed that the
- remote host speaks DECNET, instead of the default, IP/TCP.
- X.IP -s
- Toggles reporting of transfer statistics (how many articles we
- offered them, how many they accepted, etc).
- X.br
- Default is
- X.B ON.
- X.IP -d
- Toggles DEBUG output on stderr.
- This can be used to see exactly what the two systems are saying to
- each other, except for the actual article text.
- X.br
- Default is
- X.B OFF.
- X.IP -r
- Toggles requeuing of failed articles.
- A failed article is an article that we (client) offer them (remote server),
- they accept, we transmit, and then they report that they "failed"
- or dropped the article (i.e. inews(1) on the remote returned non-zero).
- If we have requeuing set, we save the list of articles that they
- failed on, and rewrite the queue file with them, so that they get
- reoffered the next time we initiate transmission to them.
- X.br
- Default is
- X.B ON.
- X.IP -a
- This flag says that the next queue file on the command line isn't
- a queue file, but is a single netnews
- article to be transmitted to the remote in a single operation.
- X.IP
- X.B NOTE:
- this option causes
- X.I nntpxmit
- to exit immediately after this transfer is done (regardless of
- whatever else is on the command line), and to exit with a code
- indicating whether the articles was successfully accepted by the
- remote server (zero exit for success, non-zero for failure).
- X.PP
- The next options set the underlying transport protocol that
- X.I nntpxmit
- uses.
- The NNTP specification assumes a TCP-style transport protocol
- underlies it (i.e. a reliable, flow-controlled, full-duplex byte
- stream).
- X.I Nntpxmit
- assumes that after doing some magic to get a descriptor,
- it can do read(2) and write(2) calls (and use stdio) to move data
- and check for errors.
- By default,
- X.I nntpxmit
- will use IP/TCP (DoD Internet Protocol suite).
- X.IP -T
- Sets transport protocol to IP/TCP for all remaining
- transfers (unless reset by other transport flags).
- Default transport.
- X.IP -D
- Sets transport protocol to DECNET for all remaining
- transfers (unless reset by other transport flags).
- X.B NOTE:
- using "::" as the hostname/queue filename separator has the
- same effect.
- X.IP -F
- This says that the hostname is a file descriptor number, already
- open to a remote server (with some reliable protocol underneath)
- that was passed to
- X.I nntpxmit
- through a fork(2).
- X.SH "THEORY OF OPERATION"
- X.PP
- X.I Nntpxmit
- implements an interactive ihave/sendme transmission system.
- Roughly, the protocol is
- X.IP 1.
- open the article,
- fetch out the message-id (required on all netnews articles),
- and send the command IHAVE <message-id> to the remote.
- X.IP 2.
- The remote will then say either "I've seen it already" or "please send
- that article to me."
- X.IP 3.
- If the response was negative,
- X.I nntpxmit
- loops back to step 1 and offers the next article (until queue file EOF).
- Otherwise,
- X.I nntpxmit
- will send the article, using SMTP [RFC821] text transmission conventions
- X(i.e. CRLF line terminators, and dot escaping).
- X.IP 4.
- X.I Nntpxmit
- waits for the remote to say whether the article was successfully
- accepted or not.
- If the answer is negative and requeuing of failed articles is enabled,
- X.I nntpxmit
- will queue this article's filename to be
- written back to the queue file at the end of the session with this
- remote.
- X.PP
- If the communcation link should fail (and
- X.I nntpxmit
- detects it through a system call error return),
- X.I nntpxmit
- will rewrite the queue file with the article filenames of the
- articles that it did not transmit (that is, we don't retransmit
- stuff we've already successfully sent and gotten back an positive
- confirmation that they got it).
- X.SH FILES
- X/tmp/nntpxmitXXXXXX
- X.SH AUTHOR
- Erik E. Fair
- X.SH "SEE ALSO"
- inews(1),
- X.br
- RFC977 \- Network News Transfer Protocol (NNTP),
- X.br
- RFC850 \- USENET Article Format standard,
- X.br
- RFC821 \- Simple Mail Transfer Protocol (SMTP),
- X.SH BUGS
- X.PP
- Always requeuing failed articles can lead to beating the remote to
- death with a list of articles that he can't accept for come structural
- reason.
- How many of these have to pile up before you should declare that
- something is seriously wrong with the remote system and stop trying?
- X.PP
- While
- X.B nntpxmit
- will lock a queue file (your version of UNIX permitting) against
- multiple invocations of itself, there is no locking with inews(1),
- which is what writes the queue files in the first place.
- Therefore, never use
- X.B nntpxmit
- on the queue files that inews(1) writes, because two processes
- writing into the same file without some kind of cooperation will
- almost certainly trash the file; move them to some other name that
- inews(1) knows nothing about, so that you won't lose articles to
- races between inews and nntpxmit.
- X.PP
- Adding inews(1) compatible locking to the C code would be much more
- trouble than it's worth, and violates the KISS principle besides.
- END_OF_FILE
- if test 5838 -ne `wc -c <'./xmit/nntpxmit.1'`; then
- echo shar: \"'./xmit/nntpxmit.1'\" unpacked with wrong size!
- fi
- # end of './xmit/nntpxmit.1'
- fi
- echo shar: End of archive 4 \(of 9\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 9 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-